import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TianshiMeterDecode {

    public TianshiMeter decode(String hexStr) {
        TianshiMeter meter = new TianshiMeter();
        int index = 8;
        String C = hexStr.substring(index, index+2);
        index += 2;
        meter.setMasterAddr(Integer.parseInt(hexStr.substring(index, index+2),16));
        index += 2;
        String CI = hexStr.substring(index, index+2);
        index += 2;
        meter.setDeviceId(hexStr.substring(index+6, index+8)
                + hexStr.substring(index+4, index+6)
                +hexStr.substring(index+2, index+4)
                +hexStr.substring(index, index+2));
        index += 8;
        meter.setManufacturerId(hexStr.substring(index+2, index+4) + hexStr.substring(index, index+2));
        index += 4;
        meter.setVersion(Integer.parseInt(hexStr.substring(index, index+2), 16));
        if ("72".equals(CI)) {
            index += 12;
        } else if ("76".equals(CI)) {
            index += 2;
        }
        index += 4;
        if ("D4".equals(C)) {
            int i = 1;
            StringBuilder imei = new StringBuilder();
            for (char c : hexStr.substring(index, index+30).toCharArray()) {
                if (i++ % 2 == 0) imei.append(c);
            }
            meter.setIMEI(imei.toString());
            index += 30;
        }
        meter.setIMSI(hexStr.substring(index+14, index+16)
                +hexStr.substring(index+12, index+14)
                +hexStr.substring(index+10, index+12)
                +hexStr.substring(index+8, index+10)
                +hexStr.substring(index+6, index+8)
                +hexStr.substring(index+4, index+5)
                +hexStr.substring(index+2, index+4)
                +hexStr.substring(index, index+2));
        index += 16;
        SimpleDateFormat sdf = new SimpleDateFormat("ssmmhhddMMyy");
        try {
            meter.setDate(sdf.parse(hexStr.substring(index, index+12)));
        } catch (ParseException e) {
            
        }
        index += 12;
        meter.setSign(Integer.parseInt(hexStr.substring(index, index+2), 16)-140);
        index += 2;
        meter.setDayCommTime(Integer.parseInt(hexStr.substring(index+2, index+4)+hexStr.substring(index, index+2), 16));
        index += 4;
        meter.setBatteryVoltage(Integer.parseInt(hexStr.substring(index+2, index+4)+hexStr.substring(index, index+2), 16));
        index += 4;
        meter.setInnerTemperature(Integer.parseInt(hexStr.substring(index+2, index+4)+hexStr.substring(index, index+2), 16));
        index += 6;
        meter.setDupFlag(hexStr.substring(index, index+4));
        index += 8;
        meter.setPosAccFlow((float) (Integer.parseInt(hexStr.substring(index+6, index+8)
                        +hexStr.substring(index+4, index+5)
                        +hexStr.substring(index+2, index+4)
                        +hexStr.substring(index, index+2), 16) * 0.001));
        index += 14;
        meter.setNegAccFlow((float) (Integer.parseInt(hexStr.substring(index+6, index+8)
                +hexStr.substring(index+4, index+5)
                +hexStr.substring(index+2, index+4)
                +hexStr.substring(index, index+2), 16) * 0.001));
        index += 12;
        meter.setAccHeat((float) (Integer.parseInt(hexStr.substring(index+6, index+8)
                +hexStr.substring(index+4, index+5)
                +hexStr.substring(index+2, index+4)
                +hexStr.substring(index, index+2), 16) * 0.1));
        index += 14;
        meter.setAccCold((float) (Integer.parseInt(hexStr.substring(index+6, index+8)
                +hexStr.substring(index+4, index+5)
                +hexStr.substring(index+2, index+4)
                +hexStr.substring(index, index+2), 16) * 0.1));
        index += 12;
        meter.setAccRunTime(Integer.parseInt(hexStr.substring(index+6, index+8)
                +hexStr.substring(index+4, index+5)
                +hexStr.substring(index+2, index+4)
                +hexStr.substring(index, index+2), 16));
        index += 12;
        meter.setDayHeat((float) (Integer.parseInt(hexStr.substring(index+6, index+8)
                +hexStr.substring(index+4, index+5)
                +hexStr.substring(index+2, index+4)
                +hexStr.substring(index, index+2), 16) * 0.1));
        index += 8;
        meter.setDayCold((float) (Integer.parseInt(hexStr.substring(index+6, index+8)
                +hexStr.substring(index+4, index+5)
                +hexStr.substring(index+2, index+4)
                +hexStr.substring(index, index+2), 16) * 0.1));
        index += 12;
        meter.setDayMaxPower((float) (Integer.parseInt(hexStr.substring(index+2, index+4)
                +hexStr.substring(index, index+2), 16) * 0.1));
        index += 4;
        try {
            meter.setDayMaxPowerDate(sdf.parse(hexStr.substring(index, index+12)));
        } catch (ParseException e) {
            
        }
        index += 16;
        meter.setDayMinPower((float) (Integer.parseInt(hexStr.substring(index+2, index+4)
                +hexStr.substring(index, index+2), 16) * 0.1));
        index += 4;
        try {
            meter.setDayMinPowerDate(sdf.parse(hexStr.substring(index, index+12)));
        } catch (ParseException e) {
            
        }
        index += 16;
        meter.setDayEffectivityHotTime(Integer.parseInt(hexStr.substring(index+2, index+4)+hexStr.substring(index, index+2), 16));
        index += 4;
        meter.setDayEffectivityColdTime(Integer.parseInt(hexStr.substring(index+2, index+4)+hexStr.substring(index, index+2), 16));
        index += 8;
        meter.setFlow((float) (Integer.parseInt(hexStr.substring(index+6, index+8)
                +hexStr.substring(index+4, index+5)
                +hexStr.substring(index+2, index+4)
                +hexStr.substring(index, index+2), 16) * 0.001));
        index += 12;
        meter.setPower((float) (Integer.parseInt(hexStr.substring(index+6, index+8)
                +hexStr.substring(index+4, index+5)
                +hexStr.substring(index+2, index+4)
                +hexStr.substring(index, index+2), 16) * 0.1));
        return meter;
    }

    public String timing(String dupFlag, Date date) {
        String hexStr = "680E006800FE510F0100";
        SimpleDateFormat sdf = new SimpleDateFormat("ssmmhhddMMyy");
        hexStr += sdf.format(date) + dupFlag;
        byte cs = 0;
        for (int i=8; i<=34; i+=2) {
            cs += Integer.valueOf(hexStr.substring(i, i+2), 16).byteValue();
        }
        hexStr += Integer.toHexString(cs & 0xff) + "16";
        return hexStr;
    }

    public static void main(String[] args) {
        TianshiMeterDecode decode = new TianshiMeterDecode();
        TianshiMeter meter = decode.decode("68030168D30272000000004323680C010000000F7F61363888311160045100000809223A1400300E19027902000413D60B0000841013000000000405CC0400008410050000000004263F00000047052704000000000000172D1F17275914080922272D000000000008092244258D000000043B00000000042D000000000285253C001800000000000000000000A200E2010000000000000000000000000000000000000000000000000000000000000000000002D926040006701B711B000000000000000002DD26040006870D870D000000000000000002BB260400060000000000000000000000000F7F17080068000A000119000C00140015001B0000000000000000000000C616");
        System.out.println(meter);

        System.out.println(decode.timing(meter.getDupFlag(), new Date()));
    }

}
